package account

import (
  "errors"
  "fmt"
  "gitee.com/yizhisamoye/GoWeChat/entity/msg"
  "gitee.com/yizhisamoye/GoWeChat/utils"
  "net/http"
  "strings"
  "time"
)

const BaseUrl = "https://api.weixin.qq.com"

//微信公众号实体
type WxAccount struct {
  appId       string
  appSecret   string
  accessToken string
  expireIn    int64
  expireTime  *time.Time
  Options     map[string]string
  msgHandleFunc map[string]func(msg *msg.WxMsg,xmlContent []byte)(*msg.WxRespMsg,error)
}

func NewWxAccount(appId, appSecret string, options ...map[string]string) (*WxAccount, error) {
  if strings.TrimSpace(appId) == "" || strings.TrimSpace(appSecret) == "" {
    return nil, errors.New("")
  }
  account := new(WxAccount)
  account.appId = appId
  account.appSecret = appSecret
  err := account.FetchAccessToken()
  if len(options) > 0 {
    account.Options = options[0]
  } else {
    account.Options = make(map[string]string)
  }
  account.msgHandleFunc=make(map[string]func(msg *msg.WxMsg,xmlContent []byte)(*msg.WxRespMsg,error))
  return account, err
}


//验证access_token是否有效
func (c WxAccount) IsAccessTokenValid() bool {
  if len(c.accessToken) == 0 {
    return false
  }
  if c.expireTime == nil {
    return false
  }
  if c.expireTime.Before(time.Now()) {
    fmt.Println(c.expireTime)
    return false
  }
  return true
}

//远程获取access_token
func (c *WxAccount) FetchAccessToken() error {
  url := fmt.Sprintf(BaseUrl+"/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s", c.appId, c.appSecret)
  resp, err := http.Get(url)
  if err != nil {
    return err
  }
  result, err := utils.CheckWxResp(resp)
  if err != nil {
    return err
  }
  if accessToken, exist := result["access_token"]; exist {
    c.accessToken = accessToken.(string)
    c.expireIn = int64(result["expires_in"].(float64))
    expireTime := time.Now()
    expireTime = expireTime.Add(time.Second * time.Duration(c.expireIn))
    c.expireTime = &expireTime
  }
  return nil
}

//取出access_token,这里专门做成一个返回值的函数，忽略了拉去token的err，主要是为了方便直接使用
func(c *WxAccount) GetAccessToken()string{
  if c.IsAccessTokenValid(){
    return c.accessToken
  }
  err:=c.FetchAccessToken()
  if err!=nil{
    return""
  }
  return c.accessToken
}
//获取微信服务器ip
func (c *WxAccount) GetServerIpList() ([]string, error) {
  if !c.IsAccessTokenValid() {
    err := c.FetchAccessToken()
    if err != nil {
      return nil, err
    }
  }
  url := fmt.Sprintf(BaseUrl+"/cgi-bin/getcallbackip?access_token=%s", c.accessToken)
  resp, err := http.Get(url)
  result, err := utils.CheckWxResp(resp)
  if err != nil {
    return nil, err
  }
  temp := result["ip_list"].([]interface{})
  ipList := make([]string, 0)
  for _, ip := range temp {
    ipList = append(ipList, ip.(string))
  }
  return ipList, nil
}

func(c *WxAccount)GetAppId()string{
  return c.appId
}